package com.xlx.openLink.snmp.imp;

import com.xlx.openLink.base.SnmpException;
import com.xlx.openLink.handler.*;
import com.xlx.openLink.snmp.SNMPComunication;
import com.xlx.openLink.snmp.base.SNMPTarget;
import com.xlx.openLink.snmp.service.SNMPAPI;
import com.xlx.openLink.uitls.DefaultConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.snmp4j.Snmp;
import org.snmp4j.Target;
import org.snmp4j.smi.Variable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author seven
 * @create 2019-06-17 10:29
 **/
@Slf4j
@Component
public class SNMPAPIImpl implements SNMPAPI {

    @Autowired
    private RefreshHandler refreshHandler;
    @Autowired
    private SetHandler setHandler;
    @Autowired
    private UpdateHandler updateHandler;
    @Autowired
    private DelHandler delHandler;
    @Autowired
    private AddHandler addHandler;
    @Autowired
    private SelectHandler selectHandler;

    /**
     * 根据mib获取对象
     *
     * @param obj
     * @param snmpTarget
     * @return
     * @throws SnmpException
     */
    @Override
    public Object getMibObject(Object obj, SNMPTarget snmpTarget) throws SnmpException, IOException {
        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            refreshHandler.reFresh(obj, snmp, target);
        } catch (Exception e) {
            throw new SnmpException(e.getMessage());
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }
        return obj;

    }

    /**
     * 设置值到mib中根据oid
     *
     * @param oid
     * @param nodeOid
     * @param value
     * @param snmpTarget
     * @throws SnmpException
     */
    @Override
    public void setOIDValue(String oid, String nodeOid, String value, SNMPTarget snmpTarget) throws SnmpException {
        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_SET);
            setHandler.setValue(oid, nodeOid, value, snmp, target);
        } catch (Exception e) {
            throw new SnmpException(e.getMessage());
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }
    }

    @Override
    public String getOIDValue(String oid, SNMPTarget snmpTarget) throws SnmpException {
        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            Variable variable = selectHandler.getValue(oid, snmp, target);
            if (variable == null) {
                return null;
            } else {
                return variable.toString();
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new SnmpException(e.getMessage());
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }
    }

    @Override
    public Long getOIDLongValue(String oid, SNMPTarget snmpTarget) throws SnmpException {
        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            Variable variable = selectHandler.getValue(oid, snmp, target);
            if (variable == null) {
                return null;
            } else {
                return variable.toLong();
            }
        } catch (Exception e) {
            throw new SnmpException(e.getMessage());
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }

    }

    /**
     * 校验是否在线
     *
     * @param snmpTarget
     * @throws SnmpException
     */
    @Override
    public boolean checkSnmpAgentActive(SNMPTarget snmpTarget) throws SnmpException {

        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            String str = selectHandler.getValue("1.3.6.1.2.1.1.1.0", snmp, target).toString();
            if (StringUtils.isNotBlank(str)) {
                return true;
            } else {
                return false;
            }
        } catch (Exception exception) {
            return false;
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }


    }

    /**
     * 获取下一个节点数据
     *
     * @param oid
     * @param snmpTarget
     * @return
     * @throws SnmpException
     */
    @Override
    public String getNextOIDValue(String oid, SNMPTarget snmpTarget) throws SnmpException {


        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            Variable value = selectHandler.getNextValue(oid, snmp, target);
            return value == null ? null : value.toString();
        } catch (Exception e) {
            throw new SnmpException(e.getMessage());
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }
    }

    /**
     * 更新值
     *
     * @param object
     * @param snmpTarget
     * @throws SnmpException
     */
    @Override
    public void update(Object object, SNMPTarget snmpTarget) throws SnmpException {

        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_SET);
            updateHandler.update(object, snmp, target);
        } catch (Exception e) {
            throw new SnmpException(e);
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }


    }

    /**
     * 获取表格数据
     *
     * @param clazz
     * @param snmpTarget
     * @return
     * @throws SnmpException
     */
    @Override
    public List getAllTableData(Class clazz, SNMPTarget snmpTarget) throws SnmpException {
        List retList = new ArrayList();
        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_GET);
            retList = selectHandler.getAllTableData(snmp, target, clazz);
            return retList;
        } catch (Exception e) {
            throw new SnmpException(e);
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }
    }

    /**
     * 获取全部表数据
     *
     * @param snmpTarget
     * @param tableOIDs
     * @return
     * @throws SnmpException
     */
    @Override
    public List<List<String>> getAllOIDTableData(SNMPTarget snmpTarget, List<String> tableOIDs) throws SnmpException, IOException {
        List<List<String>> resList = new ArrayList<>();
        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target Target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_SET);
            List list = selectHandler.getAllOIDTableData(snmp, Target, tableOIDs);
            resList = list;
            return resList;
        } catch (Exception e) {
            throw new SnmpException(e);
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }
    }

    @Override
    public void addTableRow(Object object, SNMPTarget snmpTarget) throws SnmpException, IOException {
        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target Target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_SET);
            addHandler.addTable(object, snmp, Target);
        } catch (Exception e) {
            throw new SnmpException(e);
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }
    }

    @Override
    public void delTableRow(Object object, SNMPTarget snmpTarget) throws SnmpException {
        Snmp snmp = null;
        try {
            snmp = SNMPComunication.createSnmp(snmpTarget);
            Target Target = SNMPComunication.getTarget(snmpTarget, DefaultConstant.SNMP_COMMUNITY_SET);
            delHandler.delTable(object, snmp, Target);
        } catch (Exception e) {
            throw new SnmpException(e);
        } finally {
            SNMPComunication.closeSnmp(snmp);
        }
    }


}
